﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Message.cs" company="Mar3ek">
//   http://mar3ek.wordpress.com
// </copyright>
// <summary>
//   Class representing a LightHouse message
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace LighthouseNET
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Xml.Linq;

    /// <summary>
    /// Class representing a LightHouse message
    /// </summary>
    public class Message
    {
        #region Fields

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="Message"/> class.
        /// </summary>
        /// <param name="title">The message title.</param>
        /// <param name="body">The message body.</param>
        /// <exception cref="ArgumentNullException">Title or body is null.</exception>
        public Message(string title, string body)
        {
            if (string.IsNullOrEmpty(title))
            {
                throw new ArgumentNullException("title");
            }

            if (string.IsNullOrEmpty(body))
            {
                throw new ArgumentNullException("body");
            }

            Title = title;
            Body = body;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Message"/> class. 
        /// </summary>
        /// <param name="attachmentsCount">
        /// The attachments count.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <param name="htmlBody">
        /// The HTML body.
        /// </param>
        /// <param name="commentsCount">
        /// The comments count.
        /// </param>
        /// <param name="createdAt">
        /// The created at.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="parentId">
        /// The parent id.
        /// </param>
        /// <param name="permalink">
        /// The permalink.
        /// </param>
        /// <param name="projectId">
        /// The project id.
        /// </param>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <param name="updatedAt">
        /// The updated at.
        /// </param>
        /// <param name="userId">
        /// The user id.
        /// </param>
        /// <param name="comments">
        /// The comments.
        /// </param>
        private Message(
            int attachmentsCount,
            string body,
            string htmlBody,
            int commentsCount,
            DateTime createdAt,
            int id,
            int parentId,
            string permalink,
            int projectId,
            string title,
            DateTime updatedAt,
            int userId,
            IList<Message> comments)
        {
            AttachmentsCount = attachmentsCount;
            Body = body;
            BodyHtml = htmlBody;
            CommentsCount = commentsCount;
            CreatedAt = createdAt;
            Id = id;
            ParentId = parentId;
            Permalink = permalink;
            ProjectId = projectId;
            Title = title;
            UpdatedAt = updatedAt;
            UserId = userId;
            Comments = new Collection<Message>(comments);
        }

        #region Properties

        /// <summary>
        /// Gets the attachments count.
        /// </summary>
        public int AttachmentsCount { get; private set; }

        /// <summary>
        /// Gets the body.
        /// </summary>
        public string Body { get; private set; }

        /// <summary>
        /// Gets the HTML body.
        /// </summary>
        public string BodyHtml { get; private set; }

        /// <summary>
        /// Gets the comments count.
        /// </summary>
        public int CommentsCount { get; private set; }

        /// <summary>
        /// Gets the created at.
        /// </summary>
        public DateTime CreatedAt { get; private set; }

        /// <summary>
        /// Gets the id.
        /// </summary>
        public int Id { get; private set; }

        /// <summary>
        /// Gets the parent id.
        /// </summary>
        public int ParentId { get; private set; }

        /// <summary>
        /// Gets the permalink.
        /// </summary>
        public string Permalink { get; private set; }

        /// <summary>
        /// Gets the project id.
        /// </summary>
        public int ProjectId { get; private set; }

        /// <summary>
        /// Gets the title.
        /// </summary>
        public string Title { get; private set; }

        /// <summary>
        /// Gets the updated at.
        /// </summary>
        public DateTime UpdatedAt { get; private set; }

        /// <summary>
        /// Gets the user id.
        /// </summary>
        public int UserId { get; private set; }

        /// <summary>
        /// Gets the comments.
        /// </summary>
        public Collection<Message> Comments { get; private set; }

        #endregion

        /// <summary>
        /// Parses the specified element.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>Parsed message</returns>
        internal static Message Parse(XElement element)
        {
            // ReSharper disable PossibleNullReferenceException
            int attachmentsCount;

            int.TryParse(element.Element("attachments-count").Value, out attachmentsCount);
            var body = element.Element("body").Value;
            var bodyHtml = element.Element("body-html").Value;
            int commentsCount;
            int.TryParse(element.Element("comments-count").Value, out commentsCount);
            var createdAt = Globals.DateTimeFromLighthouse(element.Element("created-at").Value);
            var id = int.Parse(element.Element("id").Value);
            int parentId;
            int.TryParse(element.Element("parent-id").Value, out parentId);
            var permalink = element.Element("permalink").Value;
            var projectId = int.Parse(element.Element("project-id").Value);
            var title = element.Element("title").Value;
            var updatedAt = Globals.DateTimeFromLighthouse(element.Element("updated-at").Value);
            var userId = int.Parse(element.Element("user-id").Value);
            var comments = element.Element("comments") != null ? element.Element("comments").Elements("comment").Select(Parse).ToList() : new List<Message>();

            // ReSharper restore PossibleNullReferenceException
            return new Message(
                attachmentsCount,
                body,
                bodyHtml,
                commentsCount,
                createdAt,
                id,
                parentId,
                permalink,
                projectId,
                title,
                updatedAt,
                userId,
                comments);
        }
    }
}
